package com.erik.lin.util;

import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Erik on 2017/6/29.
 */
public class JdbcTemplate extends org.springframework.jdbc.core.JdbcTemplate {

    static final String defalutDataSource = "dataSource";
    private final static Logger LOG = LoggerFactory.getLogger(JdbcTemplate.class);
    private static org.springframework.jdbc.core.JdbcTemplate defaultJt = (org.springframework.jdbc.core.JdbcTemplate) AppContext.getBean("jdbcTemplate");

    public JdbcTemplate(String dataSource){
        super(getDataSource(dataSource));
    }

    public static DataSource getDataSource(String dataSource){
        if(dataSource == null || "".endsWith(dataSource)) {
            LOG.info("输入dataSource为null or \"\"");
            return (DataSource) AppContext.getBean(defalutDataSource);
        }
        try {
            if(AppContext.getBean(dataSource) != null) {
                return (DataSource) AppContext.getBean(dataSource);
            }
        }catch (NoSuchBeanDefinitionException e) {
            LOG.info("容器中未找到\"{}\" bean,将动态注册此bean", dataSource);
        }

        String dSSql = "select * from dacp_dataex_datasource_conf";
        List<Map<String, Object>> dsList = defaultJt.queryForList(dSSql);
        Map rightDs = null;
        for(Map m: dsList) {
            if(m.get("id").equals(dataSource)) {
                rightDs = m;
            }
        }
        if(rightDs == null) {
            LOG.info("在dacp_dataex_datasource_conf中未找到id为\"{}\"的数据库", dataSource);
            return (DataSource) AppContext.getBean(defalutDataSource);
        }
        String dsConf = (String) rightDs.get("ds_conf");
        Gson gson = new Gson();
        HashMap<String, String> confMap = gson.fromJson(dsConf, HashMap.class);
        GenericBeanDefinition genericBeanDefinition = genRdbDsBeanDefinition(confMap.get("driverClassName"), confMap.get("url"), rightDs.get("ds_account").toString(), rightDs.get("ds_pwd").toString());
        AppContext.registerBeanDefinition(dataSource, genericBeanDefinition, null);
        return (DataSource) AppContext.getBean(dataSource);
    }

    private static GenericBeanDefinition genRdbDsBeanDefinition(String driverName, String url, String username, String password){
        GenericBeanDefinition gbd = new GenericBeanDefinition();
        MutablePropertyValues mpv = new MutablePropertyValues();
        mpv.add("driverClassName", driverName);
        mpv.add("url", url);
        mpv.add("username", username);
        mpv.add("password", password);

        //先判断数据库有没有连接池 org.apache.commons.dbcp.BasicDataSource , org.springframework.jdbc.datasource.DriverManagerDataSource
        Class clz = null;
        try{
            clz = Class.forName("org.apache.commons.dbcp.BasicDataSource");
        }catch(Exception e){
            LOG.warn("容器没有加载到连接池类：org.apache.commons.dbcp.BasicDataSource，尝试加载org.apache.tomcat.dbcp.dbcp2.BasicDataSource");
        }

        try{
            clz = Class.forName("org.apache.tomcat.dbcp.dbcp2.BasicDataSource");
        }catch(Exception e){
            LOG.warn("容器没有加载到连接池类：org.apache.tomcat.dbcp.dbcp2.BasicDataSource，使用的是直连可能会导致性能下降");
            clz = DriverManagerDataSource.class;
        }

        gbd.setBeanClass(clz);
        gbd.setPropertyValues(mpv);
        return gbd;
    }
}
